package com.mohammedalaa.valuecounterlib;

import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrHelper;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.Image;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.app.Context;

/**
 * Value Counter View
 */
public class ValueCounterView extends DependentLayout {
    private Component rootView;
    private Text valueTextView;
    private Image subButton;
    private Image addButton;
    private Component leftSeparator;
    private Component rightSeparator;
    private int minValue = 0;
    private int maxValue = 0;
    private int defaultValue = 0;
    private int valueColor = 0;
    private int stepValue = 0;
    private int outlineColor = 0;
    private int valueTextSize = 12;
    private int cornerRadius = 2;
    private int strokeWidth = 2;

    public ValueCounterView(Context context) {
        super(context);
        init(context);
    }

    public ValueCounterView(Context context, AttrSet attrs) {
        super(context, attrs);
        init(context);
        getDefaultValues(context, attrs);
    }

    public ValueCounterView(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
        getDefaultValues(context, attrs);
    }

    private void getDefaultValues(Context context, AttrSet attrs) {
        float displayDensity = AttrHelper.getDensity(context);
        float defaultStrokeWidth = displayDensity * 2f;
        float defaultCornerRadius = displayDensity * 2f;

        minValue = AttrSetUtils.getIntegerFromTypedArray(attrs, "minValue", 1);
        maxValue = AttrSetUtils.getIntegerFromTypedArray(attrs, "maxValue", 1);
        defaultValue = AttrSetUtils.getIntegerFromTypedArray(attrs, "defaultValue", 1);
        if (defaultValue < minValue || defaultValue > maxValue) {
            throw new RuntimeException("defaultValue must be in range ( minValue <= defaultValue <= maxValue)");
        }

        valueColor = AttrSetUtils.getColorFromTypedArray(attrs, "valueColor", 1);

        outlineColor = AttrSetUtils.getColorFromTypedArray(attrs, "outlineColor", 0xD81B60);
        cornerRadius = AttrSetUtils.getDimensionFromTypedArray(attrs, "cornerRadius", (int) defaultCornerRadius);
        strokeWidth = AttrSetUtils.getDimensionFromTypedArray(attrs, "strokeWidth", (int) defaultStrokeWidth);

        valueTextSize = AttrSetUtils.getDimensionFromTypedArray(attrs, "valueTextSize", 12);

        stepValue = AttrSetUtils.getIntegerFromTypedArray(attrs, "stepValue", 1);
        setValue(defaultValue);
        setValueColor(valueColor);
        setValueTextSize(valueTextSize);
        setOutlineColor(outlineColor, cornerRadius, strokeWidth, context);
    }

    private void setOutlineColor(int outlineColor, int cornerRadius, int strokeWidth, Context context) {
        ShapeElement gd = new ShapeElement();
        gd.setCornerRadius(cornerRadius);
        gd.setStroke(strokeWidth, new RgbColor(alphaColor(outlineColor, 1)));

        leftSeparator.setBackground(getShapeElement(outlineColor));
        rightSeparator.setBackground(getShapeElement(outlineColor));

        rightSeparator.getLayoutConfig().width = strokeWidth;

        leftSeparator.getLayoutConfig().width = strokeWidth;

        rootView.setBackground(gd);
    }

    private ShapeElement getShapeElement(int bgColor) {
        int color = bgColor;
        if (color < 0 && color >= -0xffffff) {
            color = color + 0xffffff + 1;
        }
        if (color > 0 && color <= 0xffffff) {
            color = alphaColor(color, 1.0f);
        }
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(new RgbColor(color));
        return shapeElement;
    }

    private int alphaColor(int rgbColor, float alpha) {
        int color = rgbColor;
        if (color < 0) {
            color = color + 0xffffff + 1;
        }
        int c1 = Math.max(0, color) << 8;
        int a1 = (int) (alpha * 255);
        return c1 + a1;
    }

    private void setValueTextSize(int valueTextSize) {
        if (valueTextSize > 0) {
            valueTextView.setTextSize(valueTextSize, Text.TextSizeType.PX);
        }
    }

    private void setValueColor(int valueColor) {
        valueTextView.setTextColor(new Color(valueColor));
    }

    private void init(Context context) {
        rootView = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_value_counter, this, true);

        valueTextView = (Text) rootView.findComponentById(ResourceTable.Id_valueTextView);

        subButton = (Image) rootView.findComponentById(ResourceTable.Id_subButton);
        addButton = (Image) rootView.findComponentById(ResourceTable.Id_addButton);
        leftSeparator = rootView.findComponentById(ResourceTable.Id_separator_left);
        rightSeparator = rootView.findComponentById(ResourceTable.Id_separator_right);

        subButton.setClickedListener(
                new ClickedListener() {
                    @Override
                    public void onClick(Component component) {
                        decrementValue();
                    }
                });

        addButton.setClickedListener(
                new ClickedListener() {
                    @Override
                    public void onClick(Component component) {
                        incrementValue();
                    }
                });
    }

    private void incrementValue() {
        int currentVal = getValue();
        if (currentVal < maxValue) {
            setValue(currentVal + stepValue);
        }
    }

    private void decrementValue() {
        int currentVal = getValue();
        if (currentVal > minValue) {
            setValue(currentVal - stepValue);
        }
    }

    public int getValueColor() {
        return valueColor;
    }

    public int getMinValue() {
        return minValue;
    }

    public void setMinValue(int minValue) {
        this.minValue = minValue;
    }

    public int getMaxValue() {
        return maxValue;
    }

    public void setMaxValue(int maxValue) {
        this.maxValue = maxValue;
    }

    /**
     * get Value
     *
     * @return int
     */
    public int getValue() {
        return defaultValue;
    }

    /**
     * set Value
     *
     * @param newValue int
     */
    public void setValue(int newValue) {
        int value;
        if (newValue < minValue) {
            value = defaultValue;
        } else if (newValue > maxValue) {
            value = defaultValue;
        } else {
            value = newValue;
        }
        valueTextView.setText(String.valueOf(value));
        this.defaultValue = value;
    }
}
